from Common import *
import DB
import time
from DictParamChecker import *

class Record:
    def __init__(self, logger, global_data):
        self.db = DB.DB(logger)
        self.logger = logger
        self.global_data = global_data
    
    def test(self, args):
        return makeReturn(Error.SUCCESS, {'hello':'world', 'from':'record'})

    def __specialInputArgsTransfer(self, args):
        '''成功返回轉換後的args，否則返回-1'''
        try:
            if 'current_time' in args:
                args['current_time'] = timestampFromString(args['current_time'] + ' 12:00')
            if 'begin_time' in args:
                args['begin_time'] = timestampFromString(args['begin_time'] + ' 00:00')
            if 'end_time' in args:
                args['end_time'] = timestampFromString(args['end_time'] + ' 23:59')
            if 'amount' in args:
                args['amount'] = yuanStrToFenInt(args['amount'])
            return args
        except:
            self.logger.error('__specialInputArgsTransfer failed. args:' + str(args))
            return -1

    def __specialValueTransfer(self, rows):
        '''转换从数据库返回的数据中的某些值
        没有返回值'''
        for i in range(0, len(rows)):
            if 'amount' in rows[i]:
                rows[i]['amount'] = fenIntToYuanStr(rows[i]['amount'])
            if 'timeme' in rows[i]:
                rows[i]['timeme'] = timestampToString(rows[i]['timeme'])
        return rows

    def addIncome(self, args):
        checker = DictParamChecker()
        checker.addParam('user_id', 'int', True)
        checker.addParam('currency_id', 'int', True)
        checker.addParam('account_id', 'int', True)
        checker.addParam('current_time', 'str', True)
        checker.addParam('amount', 'float', True)
        checker.addParam('cat1_id', 'int', True)
        checker.addParam('description', 'str', False, '')
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        args = self.__specialInputArgsTransfer(args)
        if args == -1:
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('addIncomeRecord', args)

    def addPayment(self, args):
        checker = DictParamChecker()
        checker.addParam('user_id', 'int', True)
        checker.addParam('currency_id', 'int', True)
        checker.addParam('account_id', 'int', True)
        checker.addParam('current_time', 'str', True)
        checker.addParam('amount', 'float', True)
        checker.addParam('cat1_id', 'int', True)
        checker.addParam('cat2_id', 'int', True)
        checker.addParam('description', 'str', False, '')
        # checker.addParam('is_instalment', '01', True)
        # checker.addParam('period_count', 'int', False, 0)
        # checker.addParam('period_payment', 'int', False, 0)
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        args = self.__specialInputArgsTransfer(args)
        if args == -1:
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('addPaymentRecord', args)

    def addTransfer(self, args):
        checker = DictParamChecker()
        checker.addParam('user_id', 'int', True)
        checker.addParam('currency_id', 'int', True)
        checker.addParam('current_time', 'str', True)
        checker.addParam('amount', 'float', True)
        checker.addParam('cat1_id', 'int', True)
        checker.addParam('src_account_id', 'int', True)
        checker.addParam('dst_account_id', 'int', True)
        checker.addParam('description', 'str', False, '')
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        args = self.__specialInputArgsTransfer(args)
        if args == -1:
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('addTransferRecord', args)


    def deleteIncome(self, args):
        checker = DictParamChecker()
        checker.addParam('rcd_id', 'int', True)
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('deleteIncome', args)

    def deletePayment(self, args):
        checker = DictParamChecker()
        checker.addParam('rcd_id', 'int', True)
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('deletePayment', args)

    def deleteTransfer(self, args):
        checker = DictParamChecker()
        checker.addParam('rcd_id', 'int', True)
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('deleteTransfer', args)

    def editIncome(self, args):
        checker = DictParamChecker()
        checker.addParam('rcd_id', 'int', True)
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('editIncome', args)

    def editPayment(self, args):
        checker = DictParamChecker()
        checker.addParam('rcd_id', 'int', True)
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('editPayment', args)

    def editTransfer(self, args):
        checker = DictParamChecker()
        checker.addParam('rcd_id', 'int', True)
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        return self.db.call('editTransfer', args)

    def getIncome(self, args):
        checker = DictParamChecker()
        checker.addParam('begin_time', 'str', True)
        checker.addParam('end_time', 'str', True)
        checker.addParam('account_id', 'int', False, '__NOT_SET__')
        checker.addParam('cat1_id', 'int', False, '__NOT_SET__')
        checker.addParam('user_id', 'int', False, '__NOT_SET__')
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        args = self.__specialInputArgsTransfer(args)
        if args == -1:
            return makeReturn(Error.ILLEGAL_ARGS)
        dbData = self.db.call('getIncomeRecord', args)
        if dbData['errno'] != Error.SUCCESS:
            return dbData
        dbData = dbData['data']
        # 计算总花费
        total_cost = 0
        for record in dbData:
            total_cost += record['amount']
        total_cost = fenIntToYuanStr(total_cost)
        # 转换特殊数据类型
        dbData = self.__specialValueTransfer(dbData)
        ret = {'records':dbData, 'total_cost':total_cost}
        return makeReturn(Error.SUCCESS, ret)

    def getPayment(self, args):
        checker = DictParamChecker()
        checker.addParam('begin_time', 'str', True)
        checker.addParam('end_time', 'str', True)
        checker.addParam('account_id', 'int', False, '__NOT_SET__')
        checker.addParam('cat1_id', 'int', False, '__NOT_SET__')
        checker.addParam('cat2_id', 'int', False, '__NOT_SET__')
        checker.addParam('user_id', 'int', False, '__NOT_SET__')
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        args = self.__specialInputArgsTransfer(args)
        if args == -1:
            return makeReturn(Error.ILLEGAL_ARGS)
        dbData = self.db.call('getPaymentRecord', args)
        if dbData['errno'] != Error.SUCCESS:
            return dbData
        dbData = dbData['data']
        # 计算总花费
        total_cost = 0
        for record in dbData:
            total_cost += record['amount']
        total_cost = fenIntToYuanStr(total_cost)
        # 转换特殊数据类型
        dbData = self.__specialValueTransfer(dbData)
        ret = {'records':dbData, 'total_cost':total_cost}
        return makeReturn(Error.SUCCESS, ret)

    def getTransfer(self, args):
        checker = DictParamChecker()
        checker.addParam('begin_time', 'str', True)
        checker.addParam('end_time', 'str', True)
        checker.addParam('src_account_id', 'int', False, '__NOT_SET__')
        checker.addParam('dst_account_id', 'int', False, '__NOT_SET__')
        checker.addParam('cat1_id', 'int', False, '__NOT_SET__')
        checker.addParam('user_id', 'int', False, '__NOT_SET__')
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        args = self.__specialInputArgsTransfer(args)
        if args == -1:
            return makeReturn(Error.ILLEGAL_ARGS)
        dbData = self.db.call('getTransferRecord', args)
        if dbData['errno'] != Error.SUCCESS:
            return dbData
        dbData = dbData['data']
        # 计算总花费
        total_cost = 0
        for record in dbData:
            total_cost += record['amount']
        total_cost = fenIntToYuanStr(total_cost)
        # 转换特殊数据类型
        dbData = self.__specialValueTransfer(dbData)
        ret = {'records':dbData, 'total_cost':total_cost}
        return makeReturn(Error.SUCCESS, ret)

    # 根据记账文本批量生产多个记录
    # 记账文本的格式为：
    # <MM-DD>
    # <价格> <CAT2> [描述]
    def addPaymentRecordsByText(self, args):
        checker = DictParamChecker()
        checker.addParam('user_id', 'int', True)
        checker.addParam('currency_id', 'int', True)
        checker.addParam('account_id', 'int', True)
        checker.addParam('text', 'str', True)
        args = checker.check(args)
        if type(args) == str:
            self.logger.warning(args)
            return makeReturn(Error.ILLEGAL_ARGS)
        record_time = ''
        addPaymentArgsList = []
        # 解析text中的所有记录并生成添加记录的请求参数
        lines = str(args['text']).split('\n')
        line_num = 0
        for line in lines:
            line_num += 1
            line = line.strip()   # 去掉首尾的空格
            if line == '':
                continue
            # 解析日期以检查日期格式是否正确
            try:
                full_date_str = ''
                if len(line) == 5: # mm-dd
                    full_date_str = str(time.localtime().tm_year) + '-' + line
                elif len(line) == 10: # YYYY-mm-dd
                    full_date_str = line
                if full_date_str != '':
                    time.strptime(full_date_str, '%Y-%m-%d')
                    record_time = full_date_str
                    continue
            except:
                pass
            # 解析记录
            items = line.split(' ')
            if len(items) < 2:
                self.logger.warning('items count < 2')
                return makeReturn(Error.ILLEGAL_ARGS)
            # 查看short_name是否存在
            if items[1] not in self.global_data.short_names:
                self.logger.warning('short name not exist! short_name:' + items[1])
                return makeReturn(Error.ILLEGAL_ARGS, "line number: %d"%(line_num))
            # 根据short_names获取对应的id
            ids = self.global_data.short_names[items[1]]
            cat1_id = ids[0]
            cat2_id = ids[1]
            description = ''
            if len(items) > 2:
                description = ' '.join(items[2:])
            addPaymentArgs = {'user_id':args['user_id'], \
                'account_id':args['account_id'], 'currency_id':args['currency_id'], \
                'cat1_id':cat1_id, 'cat2_id':cat2_id, 'amount':items[0], \
                'current_time':record_time, 'description':description}
            addPaymentArgsList.append(addPaymentArgs)

        # 把记录写入
        for args in addPaymentArgsList:
            ret = self.addPayment(args)
            if ret['errno'] != 0:
                return makeReturn(Error.EXECUTE_FAILED, {'req_args':args, 'last_ret':ret})
        return makeReturn(Error.SUCCESS)
